package test.processor.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import test.common.ReqHead;
import test.common.RequestMessage;
import test.common.RespHead;
import test.common.ResponseMessage;
import test.entity.UploadVehicleKeyRequest;
import test.entity.UploadVehicleKeyResponse;
import test.enums.CryptographicAlgorithm;
import test.enums.FieldType;
import test.enums.VehicleProtocolEnum;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;
import test.processor.RequestProcessor;
import test.util.HttpClient;
import test.util.TlvParseUtils;

/**
 * @author zhenjie.Ji
 * @description 车端密钥数据上传处理器
 * @date 2025/1/16 13:38
 */
public class VehicleKeyUploadProcessor implements RequestProcessor {
    @Override
    public byte[] process(String hexStringData, VehicleProtocolEnum vehicleProtocolEnum) {
        Map<String, String> parsedTLV = TlvParseUtils.parseTLV(hexStringData);
        ReqHead reqHead = new ReqHead();
        UploadVehicleKeyRequest uploadVehicleKeyRequest = new UploadVehicleKeyRequest();
        RequestMessage<UploadVehicleKeyRequest> requestMessage = new RequestMessage<>();

        // 解析请求头（REQ_HEAD）
        Map<String, String> headMap = TlvParseUtils.parseTLV(parsedTLV.get(FieldType.REQ_HEAD.getType()));
        for (Map.Entry<String, String> head : headMap.entrySet()) {
            setFieldValue(FieldType.fromType(head.getKey()), head.getValue(), reqHead, uploadVehicleKeyRequest);
        }
        requestMessage.setReqHead(reqHead);

        // 解析请求体（REQ_BODY）
        Map<String, String> bodyMap = TlvParseUtils.parseTLV(parsedTLV.get(FieldType.REQ_BODY.getType()));
        for (Map.Entry<String, String> body : bodyMap.entrySet()) {
            setFieldValue(FieldType.fromType(body.getKey()), body.getValue(), reqHead, uploadVehicleKeyRequest);
        }
        requestMessage.setReqBody(uploadVehicleKeyRequest);
        // 解析签名（REQ_SIGN）
        if (parsedTLV.containsKey(FieldType.REQ_SIGN.getType())) {
            if (parsedTLV.get(FieldType.REQ_SIGN.getType()).length() > 4) {
                Map<String, String> signMap = TlvParseUtils.parseTLV(parsedTLV.get(FieldType.REQ_SIGN.getType()));
                for (Map.Entry<String, String> sign : signMap.entrySet()) {
                    requestMessage.setSignatureValue(sign.getValue());
                }
            } else {
                requestMessage.setSignatureValue("");
            }

        }
        System.out.println(JSON.toJSONString(requestMessage));
        String post = HttpClient.post(vehicleProtocolEnum.getRequestUrl(), JSON.toJSONString(requestMessage));
        ResponseMessage<UploadVehicleKeyResponse> uploadVehicleKeyResponseResponseMessage = JSON.parseObject(post, new TypeReference<ResponseMessage<UploadVehicleKeyResponse>>() {
        });
        ByteBuffer byteBuffer = ByteBuffer.allocate(64);

        int lenth = 0;
        RespHead respHead = uploadVehicleKeyResponseResponseMessage.getRespHead();
        String transitionId = respHead.getTransitionId();
        byte[] bytes1 = transitionId.getBytes(StandardCharsets.UTF_8);

        String hexString = "10" + String.format("%02x", bytes1.length);
        byte[] bytes = TlvParseUtils.hexStringToBytes(hexString);
        writeData(byteBuffer, bytes);
        writeData(byteBuffer, bytes1);
        lenth += bytes.length + 2;
        String signatureAlg = respHead.getSignatureAlg();
        signatureAlg = "01";
        byte[] bytes3 = TlvParseUtils.hexStringToBytes(signatureAlg);
        String hexString1 = "12" + String.format("%02x", bytes3.length);
        byte[] bytes2 = TlvParseUtils.hexStringToBytes(hexString1);
        writeData(byteBuffer, bytes2);
        writeData(byteBuffer, bytes3);
        Integer resultCode = respHead.getResultCode();
        if (resultCode.equals(0)) {
            String code = "00000000";
            byte[] bytes4 = TlvParseUtils.hexStringToBytes(code);
            String hexString2 = "13" + String.format("%02x", bytes4.length);
            byte[] bytes5 = TlvParseUtils.hexStringToBytes(hexString2);
            writeData(byteBuffer, bytes5);
            writeData(byteBuffer, bytes4);
        } else {
            String code = String.format("%02x", resultCode);
            byte[] bytes4 = TlvParseUtils.hexStringToBytes(code);
            String hexString2 = "13" + String.format("%02x", bytes4.length);
            byte[] bytes5 = TlvParseUtils.hexStringToBytes(hexString2);
            writeData(byteBuffer, bytes5);
            writeData(byteBuffer, bytes4);
        }
        String resultMsg = respHead.getResultMsg();
        byte[] bytes4 = resultMsg.getBytes(StandardCharsets.UTF_8);
        String hexString2 = "14" + String.format("%02x", bytes4.length);
        byte[] bytes5 = TlvParseUtils.hexStringToBytes(hexString2);
        writeData(byteBuffer, bytes5);
        writeData(byteBuffer, bytes4);

        UploadVehicleKeyResponse respBody = uploadVehicleKeyResponseResponseMessage.getRespBody();
        if (null != respBody){
            String macAlg = respBody.getMacAlg();
            String mac = respBody.getMac();
        }else {

        }

        String signatureValue = uploadVehicleKeyResponseResponseMessage.getSignatureValue();
        System.out.println(post);
        // 获取最终的字节数组
        byte[] result = new byte[byteBuffer.position()];
        byteBuffer.flip();  // 将 buffer 切换为读取模式
        byteBuffer.get(result);
        System.out.println(TlvParseUtils.byteArrayToHex(result));
        return result;
    }

    /**
     * 设置字段值
     *
     * @param fieldType 字段类型
     * @param value     对应的值
     * @param reqHead   请求头
     * @param request   请求体
     */
    private static void setFieldValue(FieldType fieldType, String value, ReqHead reqHead, UploadVehicleKeyRequest request) {
        switch (fieldType) {
            case REQ_HEAD_TRANSITION_ID:
                reqHead.setTransitionId(TlvParseUtils.convertHexToString(value));
                break;
            case REQ_HEAD_RANDOM:
                reqHead.setRandom(TlvParseUtils.convertHexToString(value));
                break;
            case REQ_HEAD_SIGNATURE_ALG:
                if (value.equals(CryptographicAlgorithm.HmacSHA256.getTag())) {
                    reqHead.setSignatureAlg(CryptographicAlgorithm.HmacSHA256.getParam());
                }
                break;
            case REQ_BODY_VIN:
                request.setVin(TlvParseUtils.convertHexToString(value));
                break;
            case REQ_BODY_BLE_MAC:
                request.setBleMac(TlvParseUtils.convertHexToString(value));
                break;
            case REQ_BODY_ENCRYPT_ALG:
                if (value.equals(CryptographicAlgorithm.AES128.getTag())) {
                    request.setEncryptAlg(CryptographicAlgorithm.AES128.getParam());
                }
                break;
            case REQ_BODY_VEHICLE_MASTER_KEY:
                request.setVehicleMasterKey(Base64.getEncoder().encodeToString(TlvParseUtils.hexStringToBytes(value)));
                break;
            case REQ_BODY_VERSION:
                request.setVersion(value);
                break;
            default:
                // 可扩展的处理方式
                break;
        }
    }

    private static void writeData(ByteBuffer byteBuffer, byte[] data) {
        // 如果 ByteBuffer 的剩余空间不足以写入新的数据，扩展 ByteBuffer
        if (byteBuffer.remaining() < data.length) {
            // 计算新的容量，通常可以将容量扩大一倍
            int newCapacity = byteBuffer.capacity() + data.length;
            ByteBuffer newBuffer = ByteBuffer.allocate(newCapacity);
            // 将旧的 ByteBuffer 切换为读取模式
            byteBuffer.flip();
            // 将旧数据复制到新的 ByteBuffer
            newBuffer.put(byteBuffer);
            // 将 byteBuffer 引用指向新的缓冲区
            byteBuffer = newBuffer;
        }
        // 写入新数据
        byteBuffer.put(data);
    }


}
